#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include "../TIN/TIN.h"



/*PRE: tin tiene suficiente memoria reservada para una estructura de tipo TIN.
 *POST Si pudo crear la incidencia devuelve 0. Si hubo algún error devuelve -1.
 */
int TIN_Crear ( TIN* tin, int inci_id, tipo_inci_t inci_type, prior_inci_t inci_priority,
		int	inci_user, int inci_assigned_user, char* inci_date_created,
			int inci_project_id, char* inci_summary, char* inci_description){


tin->inci_id = inci_id;
tin->inci_type = inci_type;
tin->inci_priority = inci_priority;
tin->inci_user = inci_user;
tin->inci_assigned_user = inci_assigned_user;
tin->inci_date_created= (char*) malloc (sizeof(char)* (strlen(inci_date_created)+1));
if (tin->inci_date_created==NULL) return -1;
strcpy(tin->inci_date_created,inci_date_created);

tin->inci_project_id = inci_project_id;
tin->inci_summary= (char*) malloc (sizeof(char) * (strlen(inci_summary)+1));
if (tin->inci_summary==NULL) return -1;
strcpy(tin->inci_summary,inci_summary);

tin->inci_description= (char*) malloc (sizeof(char)* (strlen(inci_description)+1));
if (tin->inci_description==NULL) return -1;
strcpy(tin->inci_description,inci_description);

LS_Crear(&(tin->inci_stat_hist),sizeof(inci_status_t));
LS_Crear(&(tin->inci_comm), sizeof(inci_comment_t));

//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//tin->inci_resolved=0;
//tin->inci_date_solved=(char*)malloc(sizeof(char));
//strcpy(tin->inci_date_solved,"");
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<


return 0;

}






/*PRE tin creado.
 *POST Si devuelve 0, estructuras de control eliminadas y tin eliminada. Si devuelve
 *-1 ocurrió algún error.
 */

int TIN_Liberar( TIN* tin){
int OK;


	free(tin->inci_date_created);
	free(tin->inci_summary);
	free(tin->inci_description);
	free(tin->inci_date_solved);


	LS_Vaciar(&(tin->inci_stat_hist));
	OK = LS_Vacia(tin->inci_stat_hist);
	if (!OK) return -1;
	LS_Vaciar(&(tin->inci_comm));
	OK = LS_Vacia(tin->inci_comm);
	if (!OK) return -1;

	return 0;
}


/*PRE tin creado.
 *POST Si devuelve 0, estado actualizado. Si devuelve
 *-1 ocurrió algún error.
 */
int TIN_CambiarEstado( TIN* tin, const char* fecha, const int usuario, const char* estado){

	inci_status_t status;

	int exeStatus;
	int ok;

	status.stat_user_id= usuario;

	if (strcmp(estado,"TIN_OPEN")==0)
		status.stat_desc = TIN_OPEN;
	else if (strcmp(estado,"TIN_PROGRESS")==0)
		status.stat_desc = TIN_PROGRESS;
	else if (strcmp(estado,"TIN_RESOLVED")==0)
		status.stat_desc = TIN_RESOLVED;
	else if (strcmp(estado,"TIN_REOPEN")==0)
		status.stat_desc = TIN_REOPEN;
	else if (strcmp(estado,"TIN_CLOSED")==0)
		status.stat_desc = TIN_CLOSED;
	else{
		printf("ERROR en la carga de estado\n");
		return -1;
	}

	status.stat_date = (char*) malloc (sizeof(char) * (strlen(fecha)+1));
	if (status.stat_date == NULL) return -1;
	else strcpy (status.stat_date, fecha);

if (LS_Vacia (tin->inci_stat_hist)){
	exeStatus = LS_MoverCte(&(tin->inci_stat_hist), LS_PRIMERO);
	if (exeStatus)
	 	exeStatus= LS_Insertar(&(tin->inci_stat_hist),LS_PRIMERO,&status);
}
else {
	ok = LS_MoverCte (&(tin->inci_stat_hist), LS_SIGUIENTE );
	while (ok)
		ok = LS_MoverCte (&(tin->inci_stat_hist), LS_SIGUIENTE );

	exeStatus= LS_Insertar(&(tin->inci_stat_hist),LS_SIGUIENTE,&status);
	}
	if (exeStatus) return 0;
	else return -1;


	}


/*PRE tin creado.
 *POST Si devuelve 0, incidencia resuelta. Si devuelve
 *-1 ocurrió algún error.
 */
int TIN_Resolver( TIN* tin, const char* fecha, int usuario, resol_inci_t resolucion){

	inci_status_t status;
	int exeStatus;

	status.stat_date= (char*) malloc (sizeof(char) * (strlen(fecha)+1));
	if (status.stat_date == NULL) return -1;
	else strcpy(status.stat_date, fecha);

	status.stat_desc= TIN_RESOLVED;

  status.stat_user_id=usuario; //Cesar.

	tin->inci_resolved = resolucion;

  tin->inci_date_solved=strdup(fecha);//Cesar.

	exeStatus = LS_MoverCte(&(tin->inci_stat_hist), LS_PRIMERO);

	if (exeStatus)
		exeStatus= LS_Insertar(&(tin->inci_stat_hist),LS_PRIMERO,&status);

	if (exeStatus) return 0;
	else return -1;


}


/*PRE: tin abierto.
 *POST: Comentario registrado. Devuelve -1 si ocurrió algún error.
 */
int TIN_Comentar( TIN* tin, const char* fecha, int usuario, char* comentario){

int exeStatus;
inci_comment_t comm;
int ok;

comm.comm_date = (char*) malloc ( sizeof(char) * (strlen(fecha)+1));
if (comm.comm_date == NULL) return -1;
else strcpy (comm.comm_date, fecha);


comm.comm_user_id = usuario;

comm.comm_desc = (char*) malloc ( sizeof(char) * (strlen(comentario)+1));
if (comm.comm_desc == NULL) return -1;
else strcpy(comm.comm_desc, comentario);

if (LS_Vacia (tin->inci_comm)){
	exeStatus = LS_MoverCte(&(tin->inci_comm), LS_PRIMERO);
	if (exeStatus)
		exeStatus = LS_Insertar(&(tin->inci_comm),LS_PRIMERO,&comm);
}
else {
	ok = LS_MoverCte (&(tin->inci_comm), LS_SIGUIENTE );
	while (ok){
		ok = LS_MoverCte (&(tin->inci_comm), LS_SIGUIENTE );
		}
	exeStatus = LS_Insertar(&(tin->inci_comm),LS_SIGUIENTE,&comm);
	}

if (exeStatus) return 0;
else return -1;
}



/*PRE:
 *POST: Si pudo obtener los datos devuelve 0. Si hubo algún error devuelve -1.
 */
int TIN_GetDatos ( TIN* tin, int* inci_id, tipo_inci_t* inci_type,
	prior_inci_t* inci_priority, int* inci_user, int* inci_assigned_user,
		char** inci_date_created,int* inci_project_id, char** inci_summary,
			char** inci_description){



*inci_id = tin->inci_id;
*inci_type = tin->inci_type;
*inci_priority = tin->inci_priority;
*inci_user = tin->inci_user;
*inci_assigned_user = tin->inci_assigned_user;

(*inci_date_created) = (char*) malloc (sizeof(char)* (strlen(tin->inci_date_created)+1));
if (*inci_date_created == NULL) return -1;
strcpy(*inci_date_created, tin->inci_date_created);

*inci_project_id = tin->inci_project_id;
(*inci_summary) = (char*) malloc (sizeof(char) * (strlen(tin->inci_summary)+1));
if ((*inci_summary) == NULL) return -1;
strcpy(*inci_summary,tin->inci_summary);

(*inci_description) = (char*) malloc (sizeof(char)* (strlen(tin->inci_description)+1));
if (*inci_description == NULL) return -1;
strcpy(*inci_description,tin->inci_description);

return 0;

}


/*PRE: tin abierto. Comentarios apunta a una lista simple creada y vacía para
 *contener objetos de tipo inci_comment_t
 *POST: Si devuelve 0 devolvió en comentarios una lista de objetos
 *inci_comment_t con los datos de cada uno de los comentarios de la
 *incidencia. La memoria reservada para los strings debe ser liberada por el
 *invocador. Si devuelve -1 ocurrió un error y la lista permanece inalterada.
 */

int TIN_GetListaComentarios( const TIN* tin, TListaSimple* comentarios){

	inci_comment_t comentario;
	int exeStatus,error;

	error= LS_MoverCte(&(tin->inci_comm), LS_PRIMERO );
	if (error) {
		if(!LS_Vacia(tin->inci_comm)){
      LS_ObtenerCte(tin->inci_comm,&comentario);
      exeStatus= LS_Insertar(comentarios,LS_PRIMERO,&comentario);
      while (exeStatus && error){
        error= LS_MoverCte(&(tin->inci_comm), LS_SIGUIENTE);
        if (error) {
          LS_ObtenerCte(tin->inci_comm,&comentario);
          exeStatus= LS_Insertar(comentarios,LS_SIGUIENTE,&comentario);
        }
      }
		}
	}

if (error==0 && exeStatus==1)
	return 0;
else
	return -1;

}



/*PRE: tin abierto. Estados apunta a una lista simple creada y vacía para
 *contener objetos de tipo inci_status_t.
 *POST: Si devuelve 0 devolvió en estados una lista de objetos inci_status_t
 *con los datos de cada uno de los estados de la incidencia. La memoria
 *reservada para los strings debe ser liberada por el invocador. Si devuelve -1
 *ocurrió un error y la lista permanece inalterada.
 */
int TIN_GetListaEstados( const TIN* tin, TListaSimple* estados){

	int exeStatus, error;
	inci_status_t estado;


	error= LS_MoverCte(&(tin->inci_stat_hist), LS_PRIMERO );
	if (error) {
    if (!LS_Vacia(tin->inci_stat_hist)){
      LS_ObtenerCte(tin->inci_stat_hist,&estado);
      exeStatus= LS_Insertar(estados,LS_PRIMERO,&estado);
      while (exeStatus && error){
        error= LS_MoverCte(&(tin->inci_stat_hist), LS_SIGUIENTE);
        if (error) {
          LS_ObtenerCte(tin->inci_stat_hist,&estado);
          exeStatus= LS_Insertar(estados,LS_SIGUIENTE,&estado);
        }
      }
	  }
	}

if (error==0 && exeStatus==1)
	return 0;
else
	return -1;

}


int Get_resolucion(TIN tin, resol_inci_t* inci_resolved,char** inci_date_solved){

	*inci_resolved = tin.inci_resolved;

	*inci_date_solved = (char*) malloc (sizeof(char)* (strlen(tin.inci_date_solved)+1));
	if (*inci_date_solved)
	strcpy(*inci_date_solved,tin.inci_date_solved);

return 0;
	}
